﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser.JavaScriptHelpers
{
    #region Using Statements

    using Jint;
    using Jint.Native;
    using KLF.Lib.Browser.DOM;
    using KLF.Lib.Browser.DOM.HTML;

    #endregion

    /// <summary>
    /// This delegate is called just prior to any script running in a newly
    /// created Javascript context.
    /// </summary>
    /// <param name="context"></param>
    /// <param name="doc"></param>
    internal delegate void RegisterWithScript(RequestContext context, HTMLDocument doc);

    /// <summary>
    /// This class is intended to try and custom-tailor the Javascript context
    /// to emulate the DOM of the browser being emulated.  Examples of this are
    /// 
    /// </summary>
    internal class UserAgentScriptInterface
    {

        /// <summary>
        /// Attempt to mimic the DOM of Firefox9.
        /// </summary>
        /// <param name="context"></param>
        internal static void RegisterFirefox9(RequestContext context, HTMLDocument doc)
        {
            context.Script.SetParameter("xAnchors",
                ((JsGlobal)context.Script.Global).WrapClr(
                    new HTMLWrappedCollection<HTMLAnchorElement>(doc, "Anchors")));
            var result = context.Script.Run("var result = document.xAnchors");
            result = context.Script.Run("document.xAnchors = xAnchors;");
        }
    }

    public class UserAgent
    {
        #region Constructors

        private UserAgent()
        {
        }

        #endregion

        #region Properties

        public string appCodeName { get; set; }

        public string appName { get; set; }

        public string appVersion { get; set; }

        public bool cookieEnabled { get; set; }

        public bool isJavaEnabled { get; set; }

        public bool isTaintEnabled { get; set; }

        public string platform { get; set; }

        public Plugins plugins { get { return new Plugins(); } }

        public string userAgent { get; set; }

        public bool javaEnabled() { return isJavaEnabled; }

        internal RegisterWithScript RegisterScriptContext { get; set; }

        public bool taintEnabled() { return isTaintEnabled; }

        #endregion

        #region Methods

        /// <summary>
        /// Called before any Javascript is executed in a new context.
        /// </summary>
        /// <param name="context"></param>
        internal void RegisterWithScript(RequestContext context, HTMLDocument doc)
        {
            RegisterScriptContext(context, doc);
        }

        #endregion

        #region Common Browser Agents

        /// <summary>
        /// Simulates a Firefox 9.0 browser agent.
        /// </summary>
        /// <returns></returns>
        public static UserAgent Firefox9()
        {
            return new UserAgent()
            {
                appCodeName = "Mozilla",
                appName = "Netscape",
                appVersion = "5.0 (Windows)",
                platform = "Win32",
                userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1",
                cookieEnabled = true,
                isJavaEnabled = false,
                isTaintEnabled = false,
                RegisterScriptContext = new RegisterWithScript(UserAgentScriptInterface.RegisterFirefox9)
            };
        }

        #endregion
    }
}
